namespace Dida.Test.ParamEditor2D
{
	public class SelectController : ParamEditor2DController
	{
		bool drawingRect = false;
		Gdk.Point selectOrigin;
		Gdk.Point selectCursor;

		public override void Draw(Gdk.Drawable dr)
		{
			if (drawingRect)
			{
				Gdk.GC selectGC = new Gdk.GC(dr);
				selectGC.RgbFgColor = new Gdk.Color(255, 255, 255);

				Gdk.Rectangle rect = CalcSelectionRect();
				dr.DrawRectangle(selectGC, false, rect);
			}
		}

		private Gdk.Rectangle CalcSelectionRect()
		{
			Gdk.Rectangle rect = new Gdk.Rectangle();
			if (selectOrigin.X < selectCursor.X)
			{
				rect.X = selectOrigin.X;
				rect.Width = selectCursor.X - selectOrigin.X;
			}
			else
			{
				rect.X = selectCursor.X;
				rect.Width = selectOrigin.X - selectCursor.X;
			}

			if (selectOrigin.Y < selectCursor.Y)
			{
				rect.Y = selectOrigin.Y;
				rect.Height = selectCursor.Y - selectOrigin.Y;
			}
			else
			{
				rect.Y = selectCursor.Y;
				rect.Height = selectOrigin.Y - selectCursor.Y;
			}

			return rect;
		}

		public override void OnButtonPress(Gdk.Point ctrlPos, Vector2D logicalPos)
		{
			// see if we clicked a control point
			foreach (ControlPoint2D cp in Model.ControlPoints)
			{
				if (cp.GetRectInView(View).Contains(ctrlPos))
				{
					if (!cp.Selected)
					{
						Model.SetSelection(cp);
						
						// start dragging
					}

					return;
				}
			}

			// if we got here, we didn't hit a point, so we start drawing a selection rect.
			drawingRect = true;
			selectOrigin = ctrlPos;

			selectCursor = selectOrigin;

			Model.ClearSelection();
		}

		public override void OnButtonRelease(Gdk.Point ctrlPos, Vector2D logicalPos)
		{
			if(drawingRect)
			{
				SelectRect(CalcSelectionRect());
				QueueDrawForSelectionRect();
				drawingRect = false;
			}
		}

		private void SelectRect(Gdk.Rectangle rect)
		{
			ParamEditor2DModel model = Model;
			ParamEditor2DView view = View;
			foreach (ControlPoint2D cp in model.ControlPoints)
			{
				Gdk.Rectangle cpRect = cp.GetRectInView(view);
				cp.Selected = rect.IntersectsWith(cpRect);
			}
		}

		public override void OnMouseMotion(Gdk.Point ctrlPos, Vector2D logicalPos)
		{
			if(drawingRect)
			{
				QueueDrawForSelectionRect();
				selectCursor = ctrlPos;
				SelectRect(CalcSelectionRect());
				QueueDrawForSelectionRect();
			}
		}

		private void QueueDrawForSelectionRect()
		{
			Gdk.Rectangle rect = CalcSelectionRect();

			View.QueueDrawArea(rect.X, rect.Y, 1, rect.Height + 1);
			View.QueueDrawArea(rect.X, rect.Y, rect.Width + 1, 1);
			View.QueueDrawArea(rect.X + rect.Width, rect.Y, 1, rect.Height + 1);
			View.QueueDrawArea(rect.X, rect.Y + rect.Height, rect.Width + 1, 1);
		}
	}
}